package com.example.dynamicschedule.service;


import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.dynamicschedule.bean.*;
import com.example.dynamicschedule.dao.CkFeedbackConfigTableMapper;
import com.example.dynamicschedule.dao.CkOrderOutboundRecoveryLogMapper;
import com.example.dynamicschedule.dao.CkStopNoticePersonTimesMapper;
import com.example.dynamicschedule.utils.NoAnswerAndMissPeopleUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class PeopleCallService {
    @Autowired
    private CkFeedBackService ckFeedBackService;
    @Autowired
    private CkOrderRecoveryDataService ckOrderRecoveryDataService;
    @Autowired
    private CkStopNoticePersonService ckStopNoticePersonService;
    @Autowired
    private CkOrderNotDialedService ckOrderNotDialedService;
    @Autowired
    private CkOrderAchievementFormService ckOrderAchievementFormService;
    @Autowired
    private NoAnswerAndMissPeopleUtils noAnswerAndMissPeopleUtils;
    @Autowired
    private CkOrderLoanIntelligenceDivisionService ckOrderLoanIntelligenceDivisionService;
    @Autowired
    private CkOrderOutboundRecoveryLogMapper ckOrderOutboundRecoveryLogMapper;
    @Autowired
    private CkFeedbackConfigTableMapper ckFeedbackConfigTableMapper;
    @Autowired
    private CkStopNoticePersonTimesMapper ckStopNoticePersonTimesMapper;
    protected static final Logger logger = LoggerFactory.getLogger(PeopleCallService.class);


    /**
     * @param jsonStr
     * @param feedBackConfigMap
     */
    public void peopleCallService(String jsonStr, Map<String, CkFeedbackConfigTable> feedBackConfigMap) throws ParseException {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(date);
        logger.info("人工客服数据处理，参数：params=" + JSONUtils.toJSONString(jsonStr));
        logger.info("转换人工客服参数开始");
        JSONObject jsonObject = JSON.parseObject(jsonStr);
        Object peopleCall = jsonObject.get("人工客服");
        List<CkOrderRecoveryData> ckOrderRecoveryDatas = JSONObject.parseArray(JSON.toJSONString(peopleCall), CkOrderRecoveryData.class);
        logger.info("转换人工客服参数结束");
        CkStopNoticePersonTimes ckStopNoticePersonTimes= ckStopNoticePersonTimesMapper.selectByKey("noAnswerPeople");
        Map<String, Integer> noAnswerPeopleMap = null;
        if (ckStopNoticePersonTimes!=null) {
            String value = ckStopNoticePersonTimes.getMapValue();
            // Map<Object, Object> noAnswerPeople = redisService.hmget("noAnswerPeople");
            noAnswerPeopleMap = JSON.parseObject(value, Map.class);
        } else {
            ckStopNoticePersonTimes=new CkStopNoticePersonTimes();
            noAnswerPeopleMap = new HashMap<>();
        }
        CkFeedbackConfigTable ckFeedbackConfigTable = ckFeedbackConfigTableMapper.selectByType((byte) 3);
        String noAnswer = ckFeedbackConfigTable.getNumbers();
        logger.info("数据分类开始");
        //已经拨打
        List<CkOrderRecoveryData> ckOrderRecoveryDataList = new ArrayList<>();
        //未拨打
        List<CkOrderNotDialed> ckOrderNotDialedList = new ArrayList<>();
        //停催
        List<CkStopNoticePerson> stopCkStopNoticePeople = new ArrayList<>();
        //停催反馈码
        CkFeedbackConfigTable stopCkFeedbackConfigTable = feedBackConfigMap.get("停催");
        String stopNumbers = stopCkFeedbackConfigTable.getNumbers();
        //失联
        List<CkStopNoticePerson> missCkStopNoticePeople = new ArrayList<>();
        //失联反馈码
        CkFeedbackConfigTable missCkFeedbackConfigTable = feedBackConfigMap.get("失联");
        String missNumbers = missCkFeedbackConfigTable.getNumbers();
        //分类规则开始
        List<CkStopNoticePerson> finalMissCkStopNoticePeople = missCkStopNoticePeople;
        Map<String, Integer> finalNoAnswerPeopleMap = noAnswerPeopleMap;
        ckOrderRecoveryDatas.stream().forEach(ckOrderRecoveryData -> {
            ckOrderRecoveryData.setNotificationMethod((byte) 3);
            //ckOrderRecoveryData.setDataTime(format);
            String feedbackCode = ckOrderRecoveryData.getFeedbackCode();
            //判断已接听或者未接听
            if (StringUtils.isNotEmpty(feedbackCode)) {
                ckOrderRecoveryData.setSendTime(format);
                ckOrderRecoveryDataList.add(ckOrderRecoveryData);
                //连续三次问题
                if (finalNoAnswerPeopleMap != null&&finalNoAnswerPeopleMap.size()>0) {
                    String serialNumber = ckOrderRecoveryData.getSerialNumber();
                    if (finalNoAnswerPeopleMap.get(serialNumber) != null) {
                        if (!noAnswer.contains(feedbackCode)) {
                            finalNoAnswerPeopleMap.remove(serialNumber);
                        }
                    }
                }
                //判断停催还是失联状态
                if (stopNumbers.contains(feedbackCode)) {
                    CkStopNoticePerson ckStopNoticePerson = new CkStopNoticePerson();
                    BeanUtils.copyProperties(ckOrderRecoveryData, ckStopNoticePerson);
                    ckStopNoticePerson.setType((byte) 1);
                    ckStopNoticePerson.setDivisionMode((byte) 1);
                    ckStopNoticePerson.setIsDelete((byte) 0);

                    stopCkStopNoticePeople.add(ckStopNoticePerson);
                } else if (missNumbers.contains(feedbackCode)) {
                    CkStopNoticePerson ckStopNoticePerson = new CkStopNoticePerson();
                    BeanUtils.copyProperties(ckOrderRecoveryData, ckStopNoticePerson);
                    ckStopNoticePerson.setType((byte) 2);
                    ckStopNoticePerson.setDivisionMode((byte) 1);
                    ckStopNoticePerson.setIsDelete((byte) 0);
                    finalMissCkStopNoticePeople.add(ckStopNoticePerson);
                }
            } else {
                CkOrderNotDialed ckOrderNotDialed = new CkOrderNotDialed();
                BeanUtils.copyProperties(ckOrderRecoveryData, ckOrderNotDialed);
                ckOrderNotDialed.setNotificationMethod((byte) 3);
                ckOrderNotDialedList.add(ckOrderNotDialed);
            }
        });
        missCkStopNoticePeople = finalMissCkStopNoticePeople;
        ckStopNoticePersonTimes.setMapValue(JSON.toJSONString(finalNoAnswerPeopleMap));
        logger.info("数据分类结束");
        logger.info("判断失联表中是否出现成功联系开始");
        List<CkStopNoticePerson> contactCkStopNoticePeople = noAnswerAndMissPeopleUtils.answerPeople(ckOrderRecoveryDataList, stopNumbers, missNumbers);
        logger.info("在失联表中物理删除开始");
        if (!CollectionUtils.isEmpty(contactCkStopNoticePeople)) {
            ckStopNoticePersonService.updateForeach(contactCkStopNoticePeople);
        }
        logger.info("在失联表中物理删除结束");
        logger.info("判断失联表中是否出现成功联系结束");
        logger.info("判断未接听连续未接三次为失联开始");

        //String noAnswer = ckFeedBackService.selectByChinese("未接听");
        missCkStopNoticePeople = noAnswerAndMissPeopleUtils.noAnswerThree(ckOrderRecoveryDataList,
                noAnswer, missCkStopNoticePeople,ckStopNoticePersonTimes);
        logger.info("判断未接听连续未接三次为失联结束");
     /*   logger.info("判断失联连续三次为停催开始");
        List<CkStopNoticePerson> threes = noAnswerAndMissPeopleUtils.missPeopleThree(missCkStopNoticePeople);
        logger.info("判断失联连续三次为停催结束");
        logger.info("存储失联变为停催数据开始");
        if (!CollectionUtils.isEmpty(threes)) {
            ckStopNoticePersonService.updateForeachBySeriaNumber(threes);
        }
        logger.info("存储失联变为停催数据结束");*/

        logger.info("处理已接表数据开始");
      /*  Map<String, List<CkOrderAchievementForm>> achievementForm = noAnswerAndMissPeopleUtils.getAchievementForm(ckOrderRecoveryDataList);
        List<CkOrderAchievementForm> addCkOrderAchievementForm = achievementForm.get("add");
        List<CkOrderAchievementForm> updateCkOrderAchievementForm = achievementForm.get("update");
        logger.info("存储成绩表开始");
        if (!CollectionUtils.isEmpty(addCkOrderAchievementForm)) {
            ckOrderAchievementFormService.insertForeach(addCkOrderAchievementForm);
        }
        logger.info("存储成绩表结束");
        logger.info("更新成绩表开始");
        if (!CollectionUtils.isEmpty(updateCkOrderAchievementForm)) {
            ckOrderAchievementFormService.updateForeach(updateCkOrderAchievementForm);
        }
        logger.info("更新成绩表结束");*/
        logger.info("更新已接电话开始");

        //未接电话不计入
        List<String> serialNumberList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ckOrderRecoveryDataList)) {
            //全部计入
            List<String> serialNumbers = new ArrayList<>();
            for (CkOrderRecoveryData ckOrderRecoveryData : ckOrderRecoveryDataList) {
                String feedbackCode = ckOrderRecoveryData.getFeedbackCode();
                String serialNumber = ckOrderRecoveryData.getSerialNumber();
                if (!noAnswer.contains(feedbackCode)) {
                    serialNumberList.add(serialNumber);
                }
                serialNumbers.add(serialNumber);
            }
            List<CkOrderLoanIntelligenceDivision> ckOrderLoanIntelligenceDivisions = ckOrderLoanIntelligenceDivisionService.selectBySerialNumbers(serialNumberList);
            if (!CollectionUtils.isEmpty(ckOrderLoanIntelligenceDivisions)) {
                ckOrderLoanIntelligenceDivisions.stream().forEach(ckOrderLoanIntelligenceDivision -> ckOrderLoanIntelligenceDivision.setIsDialed(1));
                ckOrderLoanIntelligenceDivisionService.updateForEach(ckOrderLoanIntelligenceDivisions);
            }
            logger.info("更新已接电话结束");
            logger.info("因人工分案,存在并行,故删除智能分案并行结果开始");
            List<CkOrderRecoveryData> intelligenceDivisionCkOrderRecoveryData=ckOrderRecoveryDataService.selectBySerialNumbers(serialNumbers,"%"+format+"%");
            if (!CollectionUtils.isEmpty(intelligenceDivisionCkOrderRecoveryData)) {
                ckOrderRecoveryDataService.deleteForEach(intelligenceDivisionCkOrderRecoveryData);
            }
        }
        logger.info("因人工分案,存在并行,故删除智能分案并行结果结束");
        logger.info("存储已接听表开始");
        if (!CollectionUtils.isEmpty(ckOrderRecoveryDataList)) {
            ckOrderRecoveryDataService.insertForeach(ckOrderRecoveryDataList);
        }
        logger.info("存储已接听表结束");

        logger.info("处理已接表数据结束");
        logger.info("存储未接听表开始");
        if (!CollectionUtils.isEmpty(ckOrderNotDialedList)) {
            ckOrderNotDialedService.insertForeach(ckOrderNotDialedList);
        }
        logger.info("存储未接听表结束");
        logger.info("存储停催表和失联表开始");
        logger.info("失联表存储开始");
        if (!CollectionUtils.isEmpty(missCkStopNoticePeople)) {
            ckStopNoticePersonService.insertForeach(missCkStopNoticePeople);
        }
        logger.info("失联表存储结束");
        logger.info("停催表存储开始");
        if (!CollectionUtils.isEmpty(stopCkStopNoticePeople)) {
            ckStopNoticePersonService.insertForeach(stopCkStopNoticePeople);
        }
        logger.info("停催表存储结束");
        logger.info("存储智能外呼到log表开始");
        CkOrderOutboundRecoveryLog ckOrderOutboundRecoveryLog = new CkOrderOutboundRecoveryLog();
        ckOrderOutboundRecoveryLog.setDataTime(format);
        ckOrderOutboundRecoveryLog.setOutboundType("人工外呼");
        ckOrderOutboundRecoveryLog.setStatus((byte) 1);
        ckOrderOutboundRecoveryLogMapper.insert(ckOrderOutboundRecoveryLog);
        logger.info("存储智能外呼到log表结束");
        logger.info("人工客服数据处理结束");
    }

    /**
     * 获取当前日期的前两天的日期
     *
     * @param dataTime
     * @return
     * @throws ParseException
     */
    private List<String> getTwoDateBefore(String dataTime) throws ParseException {
        List<String> twoDates = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = simpleDateFormat.parse(dataTime);
        Calendar one = Calendar.getInstance();
        one.setTime(parse);
        one.set(Calendar.DATE, one.get(Calendar.DATE) - 1);
        String oneStr = simpleDateFormat.format(one.getTime());
        twoDates.add(oneStr);
        Calendar two = Calendar.getInstance();
        two.setTime(parse);
        two.set(Calendar.DATE, two.get(Calendar.DATE) - 2);
        String twoStr = simpleDateFormat.format(two.getTime());
        twoDates.add(twoStr);
        return twoDates;
    }
}
